package com.probiz.estoresa.content.web.action;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;

import com.probiz.estore.Constants;
import com.probiz.estore.catalog.service.ContentCategoryManager;
import com.probiz.estore.common.model.catalog.ContentCategory;
import com.probiz.estore.common.model.content.Content;
import com.probiz.estore.common.model.content.ContentRelatedType;
import com.probiz.estore.common.model.other.Tag;
import com.probiz.estore.common.util.DateUtil;
import com.probiz.estore.content.model.ContentFullyModel;
import com.probiz.estore.content.model.ContentRelatedTypeSearchCriteria;
import com.probiz.estore.content.model.ContentSearchCriteria;
import com.probiz.estore.content.service.AutoEvalRelatedContentManager;
import com.probiz.estore.content.service.ContentManager;
import com.probiz.estore.content.service.ContentRelatedTypeManager;
import com.probiz.estore.core.controller.GenericStoreAdminController;
import com.probiz.estore.core.exception.ApplicationException;
import com.probiz.estore.core.search.SearchCriteria;
import com.probiz.estore.core.util.I18nUtil;
import com.probiz.estore.other.service.TagManager;
import com.probiz.estore.webapp.util.RequestUtil;

public class ContentController extends GenericStoreAdminController<Content> {
	private I18nUtil i18nUtil = null;
	private ContentManager contentManager = null;
	private ContentCategoryManager contentCategoryManager = null;
	private ContentRelatedTypeManager contentRelatedTypeManager = null;
	private AutoEvalRelatedContentManager autoEvalRelatedContentManager = null;
	private TagManager tagManager = null;
    public void setContentManager(ContentManager inMgr) {
        this.contentManager = inMgr;
    }

	public void setContentCategoryManager(
			ContentCategoryManager contentCategoryManager) {
		this.contentCategoryManager = contentCategoryManager;
	}

	protected String getEntityName(Content entity) {
		return entity.getContentName();
	}

	
	public void setContentRelatedTypeManager(
			ContentRelatedTypeManager contentRelatedTypeManager) {
		this.contentRelatedTypeManager = contentRelatedTypeManager;
	}
	

	public void setAutoEvalRelatedContentManager(
			AutoEvalRelatedContentManager autoEvalRelatedContentManager) {
		this.autoEvalRelatedContentManager = autoEvalRelatedContentManager;
	}
	

	public void setTagManager(TagManager tagManager) {
		this.tagManager = tagManager;
	}

	public void setI18nUtil(I18nUtil util) {
		i18nUtil = util;
	}

	protected void initController() throws Exception {
		mgr = contentManager;
	}

	protected void preSave(HttpServletRequest request, Content entity, BindException errors) {
		String publishTimeRadio = RequestUtil.getParameterNullSafe(request, "publishTimeRadio");
		if(entity.getContentId() == null && "0".equals(publishTimeRadio)){
			entity.setPublishTime(new Date());
		}
		
	}
	
	
	
	public ModelAndView defaultAction(HttpServletRequest request,
			HttpServletResponse response) {
		ModelAndView mv = new ModelAndView("content/contentList");
		ContentCategory treeRoot = contentCategoryManager.getById(1);     
        Set<ContentCategory> categorySet=treeRoot.getChildren();
        List<ContentCategory> categoryList=new ArrayList<ContentCategory>();
        categoryList.addAll(categorySet);    
        /**-----------start:去掉了链接目录类型的----------------**/
		Iterator<ContentCategory> iter = categoryList.iterator();
		while(iter.hasNext()){
			ContentCategory contentCategory = iter.next();
			if(contentCategory.getCategoryType().equals(ContentCategory.TYPE_LINK)){
				iter.remove();
			}
		}
		/**-----------end: 去掉了链接目录类型的----------------**/
		mv.addObject("categoryList", categoryList);
	    mv.addObject("treeRoot", treeRoot);
		return mv;
	}

	public ModelAndView search(HttpServletRequest request,
			HttpServletResponse response) {
		ModelAndView mv = new ModelAndView("content/include/contentListBody");
		SearchCriteria searchCriteria = createSearchCriteria(request);
		ContentSearchCriteria contentSearchCriteria = new ContentSearchCriteria();
		try {
			// 绑定参数
			bind(request, contentSearchCriteria);
			//start:绑定树节点单击
			if(StringUtils.isNotBlank(contentSearchCriteria.getCategoryId())){
				ContentCategory category = contentCategoryManager.getById(Integer.parseInt(contentSearchCriteria.getCategoryId()));
				contentSearchCriteria.setCategoryPath(category.getCategoryPath());
			}
			//end:绑定树节点单击
			List<Content> contentList = contentManager.searchByCriteriaForController(
					contentSearchCriteria, searchCriteria);
			mv.addObject("contentList", contentList);
			mv.addObject("contentSearchCriteria", contentSearchCriteria);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return mv;
	}
	
	/**
	 * 重载edit方法，主要是去掉设置导航信息,否则列表页面跳转会有问题，（savedNavAndSearchCriteria(....)），其他处理与框架一致，
	 */
	@Override
	public ModelAndView edit(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		ModelAndView mv = new ModelAndView(formView);
		
		Content content = formBackingObject(request);
		//start:内容目录
		if(StringUtils.isNotBlank(RequestUtil.getParameterNullSafe(request, "contentCategoryId"))){
			content.setCategory(contentCategoryManager.getById(Integer.valueOf(RequestUtil.getParameterNullSafe(request, "contentCategoryId"))));
		}
		//end:内容目录
		
		//start:激活的关联推荐类型
		ContentRelatedTypeSearchCriteria contentRelatedTypeSearchCriteria = new ContentRelatedTypeSearchCriteria();
		contentRelatedTypeSearchCriteria.setStatus(Constants.FLAG_TRUE);
		contentRelatedTypeSearchCriteria.setIsApplyToContent(Constants.FLAG_TRUE);
		List<ContentRelatedType> relatedTypeList = contentRelatedTypeManager.getContentRelatedTypeBySearchCriteria(contentRelatedTypeSearchCriteria);
		mv.addObject("relatedTypeList", relatedTypeList);
		//end:激活的关联推荐类型
		
		
		mv.addObject("content", content);
		return mv;
	}
	/**
	 * 重载add方法，主要是去掉设置导航信息,否则列表页面跳转会有问题，（savedNavAndSearchCriteria(....)），其他处理与框架一致，
	 */
	public ModelAndView add(HttpServletRequest request,
			HttpServletResponse response) throws Exception 
	{
		return edit(request, response);
	}
	
	// 绑定
	private void bindReady(Content entity) {
		//绑定一个"退出发布的状态" 暂时性
		if(entity.getContentId() == null){
			entity.setStatus(Content.STATUS_INACTIVE);
		}
	}
	
	public ModelAndView save(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		// 取得Form对应的Model
		Content entity = formBackingObject(request);
		BindException errors = null;
		Map<String, Object> data = new HashMap<String, Object>();
		try {
			bindReady(entity);
			ServletRequestDataBinder binder = bindAndValidate(request, entity);
			errors = new BindException(binder.getBindingResult());
			// 传给子类的实现，后者可以继续验证和加入错误到errors
			preSave(request, entity, errors);
			if (!errors.hasErrors()) {// 里面如果出错应该抛出异常
				ContentFullyModel contentFullyModel = getContentFullyModel(request, entity, data);
				Map<String,Object> saveData = contentManager.saveFully(contentFullyModel);
				data.putAll(saveData);
				
			}
		} catch (ApplicationException e) {
			handleApplicationException(errors, e);
		}

		buildReturnInfo(data, entity, request);
		JSONObject jsonMap = JSONObject.fromObject(data);
		PrintWriter out = response.getWriter();
		out.println(jsonMap.toString());
		return null;
	}
	
	// 构造内容模型，方便保存
	private ContentFullyModel getContentFullyModel(HttpServletRequest request,	Content content, Map<String, Object> data) {
		ContentFullyModel model = new ContentFullyModel();
	
		model.setContent(content);

		// ---------- start:绑定媒体--------------
		String[] mediaIds = (String[]) ArrayUtils.clone(RequestUtil
				.getParameterValuesNullSafe(request, "mediaIds"));
		String[] mediaUrls = RequestUtil.getParameterValuesNullSafe(request,
				"mediaUrls");
		String[] mediaTypes = RequestUtil.getParameterValuesNullSafe(request,
				"mediaTypes");
		String[] mediaDescs = RequestUtil.getParameterValuesNullSafe(request,
				"mediaDescs");
		// 清理空的数据begin
		for (int i = 0; i < mediaIds.length; i++) {
			if (StringUtils.isEmpty(mediaUrls[i])) {
				mediaIds = (String[]) ArrayUtils.remove(mediaIds, i);
				mediaUrls = (String[]) ArrayUtils.remove(mediaUrls, i);
				mediaTypes = (String[]) ArrayUtils.remove(mediaTypes, i);
				mediaDescs = (String[]) ArrayUtils.remove(mediaDescs, i);
				i--; // 因为已经移除了一个元素，所以必须将游标-1，否则会跳过一个元素
			}
		}
		// 清理空的数据end
		// 传入返回map
		data.put("oldMediaIds", mediaIds);
		String[] newOrUpdatemediaIds = (String[]) ArrayUtils.clone(mediaIds);// 这里复制是为了可以在不改变request中的数据
		for (int i = 0; i < newOrUpdatemediaIds.length; i++) {
			if (newOrUpdatemediaIds[i].contains("new")) {
				// case:媒体是新增的
				newOrUpdatemediaIds[i] = "";
			} else {
				// case:媒体已存在
				newOrUpdatemediaIds[i] = mediaIds[i].substring(mediaIds[i]
						.indexOf("_") + 1);
			}
		}
		model.setMediaIds(newOrUpdatemediaIds);
		model.setMediaUrls(mediaUrls);
		model.setMediaTypes(mediaTypes);
		model.setMediaDescs(mediaDescs);
		// --------- end:绑定媒体----------------
		
		
		// --------- start: 绑定推荐关联文章----------------
		String[] relatedTypeIds = RequestUtil.getParameterValuesNullSafe(request, "relatedTypeIds");
		String[] relatedContentIds = RequestUtil.getParameterValuesNullSafe(request, "relatedContentIds");
		model.setRelatedTypeIds(relatedTypeIds);
		model.setRelatedContentIds(relatedContentIds);
		// --------- end: 绑定推荐关联文章----------------
		
		return model;
	}
	
	//更新有效期
	public ModelAndView updateExpired(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		Content content = formBackingObject(request);
		contentManager.updateExpired(content);
		Map<String, Object> data = new HashMap<String, Object>();
		buildReturnInfo(data,content,request);
		JSONObject jsonMap = JSONObject.fromObject(data);
		PrintWriter out = response.getWriter();
		out.println(jsonMap.toString());
		return null;
	}
	//删除文章
	public ModelAndView delete(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String entityId = request.getParameter(entityIdName);
		Content content = contentManager.getById(Integer.valueOf(entityId));
		contentManager.deleteFully(content);
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("contentName", content.getContentName());
		return getModelAndAjaxJsonView(data);
	}
	//删除多篇文章
	public ModelAndView multiDelete(HttpServletRequest request,
			HttpServletResponse response) {
		// 取得要删除的记录的id的列表。注意：选择框的id要是"multiIds"。
		String[] ids = request.getParameterValues("multiIds");
		if (ids != null && ids.length > 0) {
			for (String entityId : ids) {
				contentManager.deleteFully(contentManager.getById(Integer.valueOf(entityId)));
			}
		}
		return null;
	}
	//更新有效期多篇文章
	public ModelAndView multiUpdateExpired(HttpServletRequest request,
			HttpServletResponse response) {
		// 取得要更新的记录的id的列表。注意：选择框的id要是"multiIds"。
		String[] ids = request.getParameterValues("multiIds");
		if (ids != null && ids.length > 0) {
			for (String entityId : ids) {
				Content content = contentManager.getById(Integer.valueOf(entityId));
				contentManager.updateExpired(content);
			}
		}
		return null;
	}
	private void buildReturnInfo(Map<String, Object> data, Content content,
			HttpServletRequest request) {
		data.put("contentId", content.getContentId());
		data.put("contentTitle", content.getContentTitle());
		data.put("status", content.getStatus());
		data.put("statusMessage", i18nUtil.getMessage("content.status."+content.getStatus().toString()));
		data.put("publishTimeShow", DateUtil.getDateTime(content.getPublishTime()));
		if(content.getExpiredTime() == null){
			data.put("expiredTimeShow", i18nUtil.getMessage("content.validPeriod.neverInvalid"));
		}else{
			data.put("expiredTimeShow", DateUtil.getDateTime(content.getExpiredTime()));
		}	
		data.put("createTimeShow", DateUtil.getDateTime(content.getCreateTime()));
		data.put("updateTimeShow", DateUtil.getDateTime(content.getUpdateTime()));
	}
	
	/**
	 * 根据目录id获得路径全名
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ModelAndView getFullCategoryPathName(HttpServletRequest request,	HttpServletResponse response) throws Exception {
		Map<String, Object> data = new HashMap<String, Object>();
		ContentCategory contentCategory =contentCategoryManager.getById(RequestUtil.getInteger(request, "categoryId"));
		data.put("fullCategoryPathName", contentCategory.getFullCategoryPathName());
		return getModelAndAjaxJsonView(data);
	}
	
	/**
	 * 获得自动评估文章列表
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ModelAndView getAutoEvalContents(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		
		Map<String, Object> data = new HashMap<String, Object>();
		Integer contentId = RequestUtil.getInteger(request, "contentId");
		Integer relatedTypeId = RequestUtil.getInteger(request, "relatedTypeId");
		ContentRelatedType contentRelatedType = contentRelatedTypeManager.getById(relatedTypeId);
		List<Content> result ;
		if(null == contentId){
			result = new ArrayList<Content>();
		}else{
			result = autoEvalRelatedContentManager.getContentsByRuleCodeBySourceId(contentRelatedType.getRuleCode(), contentId, 0, 8);
		}
		JSONArray autoEvalContentArray = new JSONArray();
		for(Content content: result){
			JSONObject jsonContent = new JSONObject();
			jsonContent.put("id", content.getContentId());
			jsonContent.put("contentTitle", content.getContentTitle());
			jsonContent.put("imageUrl", content.getImageUrl());
			autoEvalContentArray.add(jsonContent);
		}
		data.put("autoEvalContentArray", autoEvalContentArray);
		data.put("relatedTypeId", relatedTypeId);
		return getModelAndAjaxJsonView(data);
	}
	
	/**
	 * 应用标签
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ModelAndView applyTags(HttpServletRequest request,	HttpServletResponse response) throws Exception {
		Map<String, Object> data = null;
		String tagNames = RequestUtil.getParameterNullSafe(request, "tagNames");
		String[] ids = request.getParameterValues("multiIds");
		if (ids != null && ids.length > 0) {
			for (String entityId : ids) {
				Content content = contentManager.getById(Integer.valueOf(entityId));
				data = tagManager.doSetTagField(content, Tag.MODULE_CONTENT, tagNames);
				contentManager.save(content);
			}
		}
		return getModelAndAjaxJsonView(data);
	}
}
